{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 239,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "b'Skipping line 6452: expected 8 fields, saw 9\\nSkipping line 43667: expected 8 fields, saw 10\\nSkipping line 51751: expected 8 fields, saw 9\\n'\n",
      "b'Skipping line 92038: expected 8 fields, saw 9\\nSkipping line 104319: expected 8 fields, saw 9\\nSkipping line 121768: expected 8 fields, saw 9\\n'\n",
      "b'Skipping line 144058: expected 8 fields, saw 9\\nSkipping line 150789: expected 8 fields, saw 9\\nSkipping line 157128: expected 8 fields, saw 9\\nSkipping line 180189: expected 8 fields, saw 9\\nSkipping line 185738: expected 8 fields, saw 9\\n'\n",
      "b'Skipping line 209388: expected 8 fields, saw 9\\nSkipping line 220626: expected 8 fields, saw 9\\nSkipping line 227933: expected 8 fields, saw 11\\nSkipping line 228957: expected 8 fields, saw 10\\nSkipping line 245933: expected 8 fields, saw 9\\nSkipping line 251296: expected 8 fields, saw 9\\nSkipping line 259941: expected 8 fields, saw 9\\nSkipping line 261529: expected 8 fields, saw 9\\n'\n",
      "C:\\ProgramData\\Anaconda3\\lib\\site-packages\\IPython\\core\\interactiveshell.py:2785: DtypeWarning: Columns (3) have mixed types. Specify dtype option on import or set low_memory=False.\n",
      "  interactivity=interactivity, compiler=compiler, result=result)\n"
     ]
    }
   ],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from datetime import datetime, timedelta\n",
    "from sklearn import preprocessing\n",
    "from lightfm import LightFM\n",
    "from scipy.sparse import csr_matrix \n",
    "from scipy.sparse import coo_matrix \n",
    "from sklearn.metrics import roc_auc_score\n",
    "import time\n",
    "from lightfm.evaluation import auc_score\n",
    "import pickle\n",
    "import re\n",
    "import seaborn as sns\n",
    "\n",
    "\n",
    "books = pd.read_csv('BX-Books.csv', sep=';', error_bad_lines=False, encoding=\"latin-1\")\n",
    "books.columns = ['ISBN', 'bookTitle', 'bookAuthor', 'yearOfPublication', 'publisher', 'imageUrlS', 'imageUrlM', 'imageUrlL']\n",
    "users = pd.read_csv('BX-Users.csv', sep=';', error_bad_lines=False, encoding=\"latin-1\")\n",
    "users.columns = ['userID', 'Location', 'Age']\n",
    "ratings = pd.read_csv('BX-Book-Ratings.csv', sep=';', error_bad_lines=False, encoding=\"latin-1\")\n",
    "ratings.columns = ['userID', 'ISBN', 'bookRating']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 240,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1149780, 3)"
      ]
     },
     "execution_count": 240,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ratings.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 241,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(271360, 8)"
      ]
     },
     "execution_count": 241,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "books.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 242,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(278858, 3)"
      ]
     },
     "execution_count": 242,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "users.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 243,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>userID</th>\n",
       "      <th>ISBN</th>\n",
       "      <th>bookRating</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>276725</td>\n",
       "      <td>034545104X</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>276726</td>\n",
       "      <td>0155061224</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>276727</td>\n",
       "      <td>0446520802</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>276729</td>\n",
       "      <td>052165615X</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>276729</td>\n",
       "      <td>0521795028</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   userID        ISBN  bookRating\n",
       "0  276725  034545104X           0\n",
       "1  276726  0155061224           5\n",
       "2  276727  0446520802           0\n",
       "3  276729  052165615X           3\n",
       "4  276729  0521795028           6"
      ]
     },
     "execution_count": 243,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ratings.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 244,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ISBN</th>\n",
       "      <th>bookTitle</th>\n",
       "      <th>bookAuthor</th>\n",
       "      <th>yearOfPublication</th>\n",
       "      <th>publisher</th>\n",
       "      <th>imageUrlS</th>\n",
       "      <th>imageUrlM</th>\n",
       "      <th>imageUrlL</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0195153448</td>\n",
       "      <td>Classical Mythology</td>\n",
       "      <td>Mark P. O. Morford</td>\n",
       "      <td>2002</td>\n",
       "      <td>Oxford University Press</td>\n",
       "      <td>http://images.amazon.com/images/P/0195153448.0...</td>\n",
       "      <td>http://images.amazon.com/images/P/0195153448.0...</td>\n",
       "      <td>http://images.amazon.com/images/P/0195153448.0...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0002005018</td>\n",
       "      <td>Clara Callan</td>\n",
       "      <td>Richard Bruce Wright</td>\n",
       "      <td>2001</td>\n",
       "      <td>HarperFlamingo Canada</td>\n",
       "      <td>http://images.amazon.com/images/P/0002005018.0...</td>\n",
       "      <td>http://images.amazon.com/images/P/0002005018.0...</td>\n",
       "      <td>http://images.amazon.com/images/P/0002005018.0...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0060973129</td>\n",
       "      <td>Decision in Normandy</td>\n",
       "      <td>Carlo D'Este</td>\n",
       "      <td>1991</td>\n",
       "      <td>HarperPerennial</td>\n",
       "      <td>http://images.amazon.com/images/P/0060973129.0...</td>\n",
       "      <td>http://images.amazon.com/images/P/0060973129.0...</td>\n",
       "      <td>http://images.amazon.com/images/P/0060973129.0...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0374157065</td>\n",
       "      <td>Flu: The Story of the Great Influenza Pandemic...</td>\n",
       "      <td>Gina Bari Kolata</td>\n",
       "      <td>1999</td>\n",
       "      <td>Farrar Straus Giroux</td>\n",
       "      <td>http://images.amazon.com/images/P/0374157065.0...</td>\n",
       "      <td>http://images.amazon.com/images/P/0374157065.0...</td>\n",
       "      <td>http://images.amazon.com/images/P/0374157065.0...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0393045218</td>\n",
       "      <td>The Mummies of Urumchi</td>\n",
       "      <td>E. J. W. Barber</td>\n",
       "      <td>1999</td>\n",
       "      <td>W. W. Norton &amp;amp; Company</td>\n",
       "      <td>http://images.amazon.com/images/P/0393045218.0...</td>\n",
       "      <td>http://images.amazon.com/images/P/0393045218.0...</td>\n",
       "      <td>http://images.amazon.com/images/P/0393045218.0...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         ISBN                                          bookTitle  \\\n",
       "0  0195153448                                Classical Mythology   \n",
       "1  0002005018                                       Clara Callan   \n",
       "2  0060973129                               Decision in Normandy   \n",
       "3  0374157065  Flu: The Story of the Great Influenza Pandemic...   \n",
       "4  0393045218                             The Mummies of Urumchi   \n",
       "\n",
       "             bookAuthor yearOfPublication                   publisher  \\\n",
       "0    Mark P. O. Morford              2002     Oxford University Press   \n",
       "1  Richard Bruce Wright              2001       HarperFlamingo Canada   \n",
       "2          Carlo D'Este              1991             HarperPerennial   \n",
       "3      Gina Bari Kolata              1999        Farrar Straus Giroux   \n",
       "4       E. J. W. Barber              1999  W. W. Norton &amp; Company   \n",
       "\n",
       "                                           imageUrlS  \\\n",
       "0  http://images.amazon.com/images/P/0195153448.0...   \n",
       "1  http://images.amazon.com/images/P/0002005018.0...   \n",
       "2  http://images.amazon.com/images/P/0060973129.0...   \n",
       "3  http://images.amazon.com/images/P/0374157065.0...   \n",
       "4  http://images.amazon.com/images/P/0393045218.0...   \n",
       "\n",
       "                                           imageUrlM  \\\n",
       "0  http://images.amazon.com/images/P/0195153448.0...   \n",
       "1  http://images.amazon.com/images/P/0002005018.0...   \n",
       "2  http://images.amazon.com/images/P/0060973129.0...   \n",
       "3  http://images.amazon.com/images/P/0374157065.0...   \n",
       "4  http://images.amazon.com/images/P/0393045218.0...   \n",
       "\n",
       "                                           imageUrlL  \n",
       "0  http://images.amazon.com/images/P/0195153448.0...  \n",
       "1  http://images.amazon.com/images/P/0002005018.0...  \n",
       "2  http://images.amazon.com/images/P/0060973129.0...  \n",
       "3  http://images.amazon.com/images/P/0374157065.0...  \n",
       "4  http://images.amazon.com/images/P/0393045218.0...  "
      ]
     },
     "execution_count": 244,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "books.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 245,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>userID</th>\n",
       "      <th>Location</th>\n",
       "      <th>Age</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>nyc, new york, usa</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>stockton, california, usa</td>\n",
       "      <td>18.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>moscow, yukon territory, russia</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>porto, v.n.gaia, portugal</td>\n",
       "      <td>17.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>farnborough, hants, united kingdom</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   userID                            Location   Age\n",
       "0       1                  nyc, new york, usa   NaN\n",
       "1       2           stockton, california, usa  18.0\n",
       "2       3     moscow, yukon territory, russia   NaN\n",
       "3       4           porto, v.n.gaia, portugal  17.0\n",
       "4       5  farnborough, hants, united kingdom   NaN"
      ]
     },
     "execution_count": 245,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "users.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 246,
   "metadata": {},
   "outputs": [],
   "source": [
    "books.drop(['imageUrlS', 'imageUrlM', 'imageUrlL'],axis=1,inplace=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 247,
   "metadata": {},
   "outputs": [],
   "source": [
    "books.loc[books.ISBN == '0789466953','yearOfPublication'] = 2000\n",
    "books.loc[books.ISBN == '0789466953','bookAuthor'] = \"James Buckley\"\n",
    "books.loc[books.ISBN == '0789466953','publisher'] = \"DK Publishing Inc\"\n",
    "books.loc[books.ISBN == '0789466953','bookTitle'] = \"DK Readers: Creating the X-Men, How Comic Books Come to Life (Level 4: Proficient Readers)\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 248,
   "metadata": {},
   "outputs": [],
   "source": [
    "books.loc[books.ISBN == '078946697X','yearOfPublication'] = 2000\n",
    "books.loc[books.ISBN == '078946697X','bookAuthor'] = \"Michael Teitelbaum\"\n",
    "books.loc[books.ISBN == '078946697X','publisher'] = \"DK Publishing Inc\"\n",
    "books.loc[books.ISBN == '078946697X','bookTitle'] = \"DK Readers: Creating the X-Men, How It All Began (Level 4: Proficient Readers)\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 249,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ISBN</th>\n",
       "      <th>bookTitle</th>\n",
       "      <th>bookAuthor</th>\n",
       "      <th>yearOfPublication</th>\n",
       "      <th>publisher</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>209538</th>\n",
       "      <td>078946697X</td>\n",
       "      <td>DK Readers: Creating the X-Men, How It All Beg...</td>\n",
       "      <td>Michael Teitelbaum</td>\n",
       "      <td>2000</td>\n",
       "      <td>DK Publishing Inc</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>221678</th>\n",
       "      <td>0789466953</td>\n",
       "      <td>DK Readers: Creating the X-Men, How Comic Book...</td>\n",
       "      <td>James Buckley</td>\n",
       "      <td>2000</td>\n",
       "      <td>DK Publishing Inc</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "              ISBN                                          bookTitle  \\\n",
       "209538  078946697X  DK Readers: Creating the X-Men, How It All Beg...   \n",
       "221678  0789466953  DK Readers: Creating the X-Men, How Comic Book...   \n",
       "\n",
       "                bookAuthor yearOfPublication          publisher  \n",
       "209538  Michael Teitelbaum              2000  DK Publishing Inc  \n",
       "221678       James Buckley              2000  DK Publishing Inc  "
      ]
     },
     "execution_count": 249,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "books.loc[(books.ISBN == '0789466953') | (books.ISBN == '078946697X'),:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 250,
   "metadata": {},
   "outputs": [],
   "source": [
    "books.loc[books.ISBN == '2070426769','yearOfPublication'] = 2003\n",
    "books.loc[books.ISBN == '2070426769','bookAuthor'] = \"Jean-Marie Gustave Le ClÃ?Â©zio\"\n",
    "books.loc[books.ISBN == '2070426769','publisher'] = \"Gallimard\"\n",
    "books.loc[books.ISBN == '2070426769','bookTitle'] = \"Peuple du ciel, suivi de 'Les Bergers\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 251,
   "metadata": {},
   "outputs": [],
   "source": [
    "books.yearOfPublication=pd.to_numeric(books.yearOfPublication, errors='coerce')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 252,
   "metadata": {},
   "outputs": [],
   "source": [
    "books.loc[(books.yearOfPublication > 2006) | (books.yearOfPublication == 0),'yearOfPublication'] = np.NAN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 253,
   "metadata": {},
   "outputs": [],
   "source": [
    "books.yearOfPublication.fillna(round(books.yearOfPublication.mean()), inplace=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 254,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0"
      ]
     },
     "execution_count": 254,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "books.yearOfPublication.isnull().sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 255,
   "metadata": {},
   "outputs": [],
   "source": [
    "books.loc[(books.ISBN == '193169656X'),'publisher'] = 'other'\n",
    "books.loc[(books.ISBN == '1931696993'),'publisher'] = 'other'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 256,
   "metadata": {},
   "outputs": [],
   "source": [
    "users.loc[(users.Age > 90) | (users.Age < 5), 'Age'] = np.nan"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 257,
   "metadata": {},
   "outputs": [],
   "source": [
    "users.Age = users.Age.fillna(users.Age.mean())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 258,
   "metadata": {},
   "outputs": [],
   "source": [
    "users.Age = users.Age.astype(np.int32)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 259,
   "metadata": {},
   "outputs": [],
   "source": [
    "ratings_new = ratings[ratings.ISBN.isin(books.ISBN)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 260,
   "metadata": {},
   "outputs": [],
   "source": [
    "ratings = ratings[ratings.userID.isin(users.userID)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 261,
   "metadata": {},
   "outputs": [],
   "source": [
    "ratings_explicit = ratings_new[ratings_new.bookRating != 0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 262,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.countplot(data=ratings_explicit , x='bookRating')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 274,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(58174, 3)"
      ]
     },
     "execution_count": 274,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "counts1 = ratings_explicit['userID'].value_counts()\n",
    "ratings_explicit = ratings_explicit[ratings_explicit['userID'].isin(counts1[counts1 >= 20].index)]\n",
    "counts = ratings_explicit['bookRating'].value_counts()\n",
    "ratings_explicit = ratings_explicit[ratings_explicit['bookRating'].isin(counts[counts >= 20].index)]\n",
    "ratings_explicit.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 275,
   "metadata": {},
   "outputs": [],
   "source": [
    "def informed_train_test(rating_df, train_ratio):\n",
    "    split_cut = np.int(np.round(rating_df.shape[0] * train_ratio))\n",
    "    train_df = rating_df.iloc[0:split_cut]\n",
    "    test_df = rating_df.iloc[split_cut::]\n",
    "    test_df = test_df[(test_df['userID'].isin(train_df['userID'])) & (test_df['ISBN'].isin(train_df['ISBN']))]\n",
    "    id_cols = ['userID', 'ISBN']\n",
    "    trans_cat_train = dict()\n",
    "    trans_cat_test = dict()\n",
    "    for k in id_cols:\n",
    "        cate_enc = preprocessing.LabelEncoder()\n",
    "        trans_cat_train[k] = cate_enc.fit_transform(train_df[k].values)\n",
    "        trans_cat_test[k] = cate_enc.transform(test_df[k].values)\n",
    "\n",
    "    # --- Encode ratings:\n",
    "    cate_enc = preprocessing.LabelEncoder()\n",
    "    ratings = dict()\n",
    "    ratings['train'] = cate_enc.fit_transform(train_df.bookRating)\n",
    "    ratings['test'] = cate_enc.transform(test_df.bookRating)\n",
    "\n",
    "    n_users = len(np.unique(trans_cat_train['userID']))\n",
    "    n_items = len(np.unique(trans_cat_train['ISBN']))\n",
    "\n",
    "\n",
    "    train = coo_matrix((ratings['train'], (trans_cat_train['userID'], \\\n",
    "                                                          trans_cat_train['ISBN'])) \\\n",
    "                                      , shape=(n_users, n_items))\n",
    "    test = coo_matrix((ratings['test'], (trans_cat_test['userID'], \\\n",
    "                                                        trans_cat_test['ISBN'])) \\\n",
    "                                     , shape=(n_users, n_items))\n",
    "    return train, test, train_df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 276,
   "metadata": {},
   "outputs": [],
   "source": [
    "train, test, raw_train_df = informed_train_test(ratings_explicit, .8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 277,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--- Run time:  0.3664984504381816 mins ---\n",
      "Train AUC Score: 0.9980106353759766\n",
      "Test AUC Score: 0.6126589179039001\n"
     ]
    }
   ],
   "source": [
    "start_time = time.time()\n",
    "model=LightFM(no_components=115,learning_rate=0.027,loss='warp')\n",
    "model.fit(train,epochs=12,num_threads=4)\n",
    "# with open('saved_model','wb') as f:\n",
    "#     saved_model={'model':model}\n",
    "#     pickle.dump(saved_model, f)\n",
    "auc_train = auc_score(model, train).mean()\n",
    "auc_test = auc_score(model, test).mean()\n",
    "\n",
    "print(\"--- Run time:  {} mins ---\".format((time.time() - start_time)/60))\n",
    "print(\"Train AUC Score: {}\".format(auc_train))\n",
    "print(\"Test AUC Score: {}\".format(auc_test))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 267,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(87, 37128)\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>ISBN</th>\n",
       "      <th>0000913154</th>\n",
       "      <th>0001046438</th>\n",
       "      <th>000104687X</th>\n",
       "      <th>0001047213</th>\n",
       "      <th>0001047973</th>\n",
       "      <th>0001048082</th>\n",
       "      <th>0001053736</th>\n",
       "      <th>0001053744</th>\n",
       "      <th>0001056107</th>\n",
       "      <th>0001845039</th>\n",
       "      <th>...</th>\n",
       "      <th>9997411757</th>\n",
       "      <th>999750805X</th>\n",
       "      <th>9997519086</th>\n",
       "      <th>9997555635</th>\n",
       "      <th>B00001U0CP</th>\n",
       "      <th>B00005TZWI</th>\n",
       "      <th>B00007FYKW</th>\n",
       "      <th>B0000DYXID</th>\n",
       "      <th>B0000T6KHI</th>\n",
       "      <th>B000234N3A</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>userID</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>4385</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6251</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6575</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7346</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11676</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>10</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 37128 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "ISBN    0000913154  0001046438  000104687X  0001047213  0001047973  \\\n",
       "userID                                                               \n",
       "4385             0           0           0           0           0   \n",
       "6251             0           0           0           0           0   \n",
       "6575             0           0           0           0           0   \n",
       "7346             0           0           0           0           0   \n",
       "11676            0           0           0           0           0   \n",
       "\n",
       "ISBN    0001048082  0001053736  0001053744  0001056107  0001845039  \\\n",
       "userID                                                               \n",
       "4385             0           0           0           0           0   \n",
       "6251             0           0           0           0           0   \n",
       "6575             0           0           0           0           0   \n",
       "7346             0           0           0           0           0   \n",
       "11676            0           0           0           0           0   \n",
       "\n",
       "ISBN       ...      9997411757  999750805X  9997519086  9997555635  \\\n",
       "userID     ...                                                       \n",
       "4385       ...               0           0           0           0   \n",
       "6251       ...               0           0           0           0   \n",
       "6575       ...               0           0           0           0   \n",
       "7346       ...               0           0           0           0   \n",
       "11676      ...               0           0           0           0   \n",
       "\n",
       "ISBN    B00001U0CP  B00005TZWI  B00007FYKW  B0000DYXID  B0000T6KHI  B000234N3A  \n",
       "userID                                                                          \n",
       "4385             0           0           0           0           0           0  \n",
       "6251             0           0           0           0           0           0  \n",
       "6575             0           0           0           0           0           0  \n",
       "7346             0           0           0           0           0           0  \n",
       "11676            0           0           0          10           0           0  \n",
       "\n",
       "[5 rows x 37128 columns]"
      ]
     },
     "execution_count": 267,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "user_item_matrix = raw_train_df.pivot(index='userID', columns='ISBN', values='bookRating')\n",
    "user_item_matrix.fillna(0, inplace = True)\n",
    "user_item_matrix = user_item_matrix.astype(np.int32)\n",
    "print(user_item_matrix.shape)\n",
    "user_item_matrix.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 268,
   "metadata": {},
   "outputs": [],
   "source": [
    "def user_item_dikts(interaction_matrix, items_df):\n",
    "    user_ids = list(interaction_matrix.index)\n",
    "    user_dikt = {}\n",
    "    counter = 0 \n",
    "    for i in user_ids:\n",
    "        user_dikt[i] = counter\n",
    "        counter += 1\n",
    "\n",
    "    item_dikt ={}\n",
    "    for i in range(items_df.shape[0]):\n",
    "        item_dikt[(items_df.loc[i,'ISBN'])] = items_df.loc[i,'bookTitle']\n",
    "    \n",
    "    return user_dikt, item_dikt    \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 269,
   "metadata": {},
   "outputs": [],
   "source": [
    "def similar_recommendation(model, interaction_matrix, user_id, user_dikt, \n",
    "                               item_dikt,threshold = 0,number_rec_items = 15):\n",
    "\n",
    "    #Function to produce user recommendations\n",
    "\n",
    "    n_users, n_items = interaction_matrix.shape\n",
    "    user_x = user_dikt[user_id]\n",
    "    scores = pd.Series(model.predict(user_x,np.arange(n_items)))\n",
    "    scores.index = interaction_matrix.columns\n",
    "    scores = list(pd.Series(scores.sort_values(ascending=False).index))\n",
    "    \n",
    "    known_items = list(pd.Series(interaction_matrix.loc[user_id,:][interaction_matrix.loc[user_id,:] > threshold].index).sort_values(ascending=False))\n",
    "    \n",
    "    scores = [x for x in scores if x not in known_items]\n",
    "    score_list = scores[0:number_rec_items]\n",
    "    known_items = list(pd.Series(known_items).apply(lambda x: item_dikt[x]))\n",
    "    scores = list(pd.Series(score_list).apply(lambda x: item_dikt[x]))\n",
    "\n",
    "    print(\"Items that were liked by the User:\")\n",
    "    counter = 1\n",
    "    for i in known_items[:25]:\n",
    "        print(str(counter) + '- ' + i)\n",
    "        counter+=1\n",
    "\n",
    "    print(\"\\n Recommended Items:\")\n",
    "    counter = 1\n",
    "    for i in scores:\n",
    "        print(str(counter) + '- ' + i)\n",
    "        counter+=1\n",
    "#     return score_list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 270,
   "metadata": {},
   "outputs": [],
   "source": [
    "def users_for_item(model,interaction_matrix,ISBN,number_of_user):\n",
    "  \n",
    "    #Funnction to produce a list of top N interested users for a given item\n",
    "\n",
    "    n_users, n_items = interaction_matrix.shape\n",
    "    x = np.array(interaction_matrix.columns)\n",
    "    scores = pd.Series(model.predict(np.arange(n_users), np.repeat(x.searchsorted(ISBN),n_users)))\n",
    "    user_list = list(interaction_matrix.index[scores.sort_values(ascending=False).head(number_of_user).index])\n",
    "    return user_list "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 271,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics.pairwise import cosine_similarity\n",
    "\n",
    "def item_emdedding_distance_matrix(model,interaction_matrix):\n",
    "\n",
    "#     Function to create item-item distance embedding matrix\n",
    "\n",
    "    df_item_norm_sparse = csr_matrix(model.item_embeddings)\n",
    "    similarities = cosine_similarity(df_item_norm_sparse)\n",
    "    item_emdedding_distance_matrix = pd.DataFrame(similarities)\n",
    "    item_emdedding_distance_matrix.columns = interaction_matrix.columns\n",
    "    item_emdedding_distance_matrix.index = interaction_matrix.columns\n",
    "    return item_emdedding_distance_matrix\n",
    "\n",
    "def also_bought_recommendation(item_emdedding_distance_matrix, item_id, \n",
    "                             item_dikt, n_items = 4):\n",
    "\n",
    "#     Function to create item-item recommendation\n",
    "\n",
    "    recommended_items = list(pd.Series(item_emdedding_distance_matrix.loc[item_id,:]. \\\n",
    "                                  sort_values(ascending = False).head(n_items+1). \\\n",
    "                                  index[1:n_items+1]))\n",
    "    \n",
    "    print(\"Item of interest :{}\".format(item_dikt[item_id]))\n",
    "    print(\"Items that are frequently bought together:\")\n",
    "    counter = 1\n",
    "    for i in recommended_items:\n",
    "        print(str(counter) + '- ' +  item_dikt[i])\n",
    "        counter+=1\n",
    "    return recommended_items"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 272,
   "metadata": {},
   "outputs": [],
   "source": [
    "user_dikt, item_dikt = user_item_dikts(user_item_matrix, books)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 219,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Items that were liked by the User:\n",
      "1- The Devil You Know\n",
      "2- Harlequin Valentine\n",
      "3- Shout!: The Beatles in Their Generation\n",
      "4- Sandman: The Dream Hunters\n",
      "5- Dream Country (Sandman, Book 3)\n",
      "6- Assata: An Autobiography (Lawrence Hill &amp; Co.)\n",
      "7- The Golden Compass (His Dark Materials, Book 1)\n",
      "8- The Fellowship of the Ring (The Lord of the Rings, Part 1)\n",
      "9- The Hobbit: or There and Back Again\n",
      "10- Harry Potter and the Sorcerer's Stone (Book 1)\n",
      "11- Something Wicked This Way Comes\n",
      "12- Martian Chronicles\n",
      "13- Animal Farm\n",
      "14- 1984\n",
      "15- The Dark Half\n",
      "16- Harry Potter and the Goblet of Fire (Book 4)\n",
      "17- Harry Potter and the Prisoner of Azkaban (Book 3)\n",
      "18- Harry Potter and the Prisoner of Azkaban (Book 3)\n",
      "19- Harry Potter and the Chamber of Secrets (Book 2)\n",
      "20- Harry Potter and the Chamber of Secrets (Book 2)\n",
      "21- The Bonesetter's Daughter\n",
      "22- The Wolves in the Walls\n",
      "23- Stardust\n",
      "24- Martian Chronicles\n",
      "25- American Gods: A Novel\n",
      "\n",
      " Recommended Items:\n",
      "1- Harry Potter and the Order of the Phoenix (Book 5)\n",
      "2- Harry Potter and the Sorcerer's Stone (Harry Potter (Paperback))\n",
      "3- Fahrenheit 451\n",
      "4- To Kill a Mockingbird\n",
      "5- The Two Towers (The Lord of the Rings, Part 2)\n",
      "6- The Hobbit : The Enchanting Prelude to The Lord of the Rings\n",
      "7- Harry Potter and the Goblet of Fire (Book 4)\n",
      "8- Interview with the Vampire\n",
      "9- Lord of the Flies\n",
      "10- Coraline\n",
      "11- The Bad Beginning (A Series of Unfortunate Events, Book 1)\n",
      "12- The Joy Luck Club\n",
      "13- Stupid White Men ...and Other Sorry Excuses for the State of the Nation!\n",
      "14- Sophie's World: A Novel About the History of Philosophy\n",
      "15- A Is for Alibi (Kinsey Millhone Mysteries (Paperback))\n"
     ]
    }
   ],
   "source": [
    "similar_recommendation(model, user_item_matrix, 254, user_dikt, item_dikt,threshold = 7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 235,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[98391, 5499, 136735, 156214, 96473, 83443, 67775, 28666, 115929, 42323]"
      ]
     },
     "execution_count": 235,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "users_for_item(model, user_item_matrix, '0195153448', 10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 273,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Item of interest :Three Fates\n",
      "Items that are frequently bought together:\n",
      "1- Surrender to Love (Avon Historical Romance)\n",
      "2- Landower Legacy\n",
      "3- Ranch Wife\n",
      "4- Sara's Song\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "['0380806304', '0449207277', '0816513864', '0821776711']"
      ]
     },
     "execution_count": 273,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "item_embedings = item_emdedding_distance_matrix(model,user_item_matrix)\n",
    "also_bought_recommendation(item_embedings,'B0000T6KHI' ,item_dikt)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
